package com.briup.jdk8.day02;



import com.briup.corejava.day22.Student;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 23【问答】提供泛型方法,可以拷贝对象(主要指属性值),并且可以忽略属性(可以是一个,也可以是多个)不复制
 * 要求: 不能写死对象和属性,可灵活复制以及忽略.
 * 例如Student s = new Student(1,"briup","000000",20)
 * 属性对应为id,name,password,age
 *
 * 解析：无论传入什么对象，都可以进行复制
 */
public class Test5 {
    public static void main(String[] args) {
        Copy<Student> c = new Copy<>();
        Class<?> kaobei = c.getClass("com.briup.corejava.day22.Student");
        Map<String,Object> map=new HashMap<>();
        map.put("age",20);
        map.put("name","tom");
        Student student = null;
        try {
            student = c.getInstance(kaobei, map);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        System.out.println(student);


    }
}
class Copy<T> {
    class Model{
        String name;
        Object data;
        Class<?> type;
    }

    public Object copyProperty(T t){
        Class<?> rClazz = t.getClass();
        // 获得属性名字、类型、值

        return null;
    }

    // 获取Class对象和属性列表
    public Class<?> getClass(String className){
        Class<?> clazz = null;
        try {
            clazz = Class.forName(className);
            // 输出属性列表
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field f : declaredFields){
                String name = f.getName();
                System.out.println("name = " + name);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return clazz;
    }
    // 创建对象
    public T getInstance(Class<?> clazz, Map<String,Object> map) throws Exception {
        Object o = clazz.getConstructor().newInstance();
        // 获得所有的set方法
        map.forEach((k,v)->{
            // 直接破开k的访问权限
            try {
                Field f = clazz.getDeclaredField(k);
                f.setAccessible(true);
                f.set(o,map.get(k));
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });

        return (T) o;
    }
}
